#ifndef SPECTRUMEXPORTER_H
#define SPECTRUMEXPORTER_H

#include <QObject>
#include <QString>
#include <QTextStream>
#include <QVector>
#include <QMap>
#include <functional>
#include "dataspecification.h"
#include "abstractdata.h"
#include "stringdata.h"
#include "writer.h"

// 添加csv库头文件引用
namespace QtCSV {
    class StringData;
    class Writer;
}

/**
 * @brief 图谱导出适配器类
 * 
 * 该类负责将各种类型的图谱导出为CSV/Excel等格式
 * 支持所有已知的图谱类型，并且可以扩展支持新图谱类型
 */
class SpectrumExporter : public QObject
{
    Q_OBJECT
public:
    /**
     * @brief 导出格式枚举
     */
    enum ExportFormat
    {
        CSV = 0,        ///< CSV格式
        EXCEL = 1,      ///< Excel格式
        JSON = 2,       ///< JSON格式
        XML = 3         ///< XML格式
    };

    /**
     * @brief 二进制数据导出选项
     */
    enum BinaryExportOption
    {
        HEXSTRING_SHORT = 0,   ///< 简短的十六进制字符串（默认，前50字节）
        HEXSTRING_FULL = 1,    ///< 完整的十六进制字符串
        BASE64_FULL = 2,       ///< 完整的Base64编码
        NONE = 3               ///< 不导出二进制数据
    };

    /**
     * @brief 导出选项结构体
     */
    struct ExportOptions
    {
        bool addBOM;                   ///< 是否添加UTF-8 BOM
        bool exportFileHeader;         ///< 是否导出文件头信息
        bool exportSpectrumBasicInfo;  ///< 是否导出图谱基本信息
        bool exportSpectrumExtInfo;    ///< 是否导出图谱扩展信息
        BinaryExportOption binaryOption; ///< 二进制数据导出选项
        QList<DataSpecificationGW::SpectrumTypeCode> spectrumTypes; ///< 要导出的图谱类型，空表示全部

        ExportOptions() : 
            addBOM(true),
            exportFileHeader(true),
            exportSpectrumBasicInfo(true),
            exportSpectrumExtInfo(true),
            binaryOption(HEXSTRING_SHORT)
        {}
    };

    /**
     * @brief 单例获取方法
     * @return 导出器实例
     */
    static SpectrumExporter* instance();
    
    /**
     * @brief 导出数据到文件
     * @param filePath 目标文件路径
     * @param specification 数据规范对象
     * @param format 导出格式
     * @param options 导出选项，默认为全部导出
     * @return 是否导出成功
     */
    bool exportToFile(const QString& filePath, 
                     DataSpecificationGW::DataSpecification* specification,
                     ExportFormat format, const ExportOptions& options = ExportOptions());
    
    /**
     * @brief 获取支持的图谱类型列表
     * @return 支持导出的图谱类型列表
     */
    QVector<int> supportedSpectrumTypes() const;
    
    /**
     * @brief 注册自定义导出处理器
     * @param spectrumTypeCode 图谱类型编码
     * @param handler 处理函数
     */
    void registerExportHandler(int spectrumTypeCode, 
                              std::function<bool(QTextStream&, DataSpecificationGW::Spectrum*)> handler);

signals:
    /**
     * @brief 导出进度更新信号
     * @param value 进度值(0-100)
     * @param message 进度信息
     */
    void progressUpdated(int value, const QString& message);

private:
    explicit SpectrumExporter(QObject* parent = nullptr);
    ~SpectrumExporter();
    
    /**
     * @brief 初始化默认导出处理器
     */
    void initDefaultHandlers();
    
    /**
     * @brief 将DataSpecification转换为CSV数据对象
     * @param specification 数据规范对象
     * @param options 导出选项
     * @return CSV数据对象
     */
    QtCSV::StringData convertToCSVData(DataSpecificationGW::DataSpecification* specification, const ExportOptions& options);

    /**
     * @brief 创建CSV表头
     * @param specification 数据规范对象
     * @return CSV表头行数据
     */
    QList<QString> createCSVHeader(DataSpecificationGW::DataSpecification* specification);

    /**
     * @brief 添加图谱数据到CSV数据对象
     * @param data CSV数据对象
     * @param spectrum 图谱对象
     * @param options 导出选项
     * @return 是否成功
     */
    bool addSpectrumToCSVData(QtCSV::StringData& data, DataSpecificationGW::Spectrum* spectrum, const ExportOptions& options);
    
    /**
     * @brief 添加AE幅值图谱数据到CSV数据对象
     * @param data CSV数据对象
     * @param spectrum 图谱对象
     * @param options 导出选项
     * @return 是否成功
     */
    bool addAEAmpSpectrumData(QtCSV::StringData& data, DataSpecificationGW::Spectrum* spectrum, const ExportOptions& options = ExportOptions());
    
    /**
     * @brief 添加AE相位图谱数据到CSV数据对象
     * @param data CSV数据对象
     * @param spectrum 图谱对象
     * @param options 导出选项
     * @return 是否成功
     */
    bool addAEPhaseSpectrumData(QtCSV::StringData& data, DataSpecificationGW::Spectrum* spectrum, const ExportOptions& options = ExportOptions());
    
    /**
     * @brief 添加AE脉冲图谱数据到CSV数据对象
     * @param data CSV数据对象
     * @param spectrum 图谱对象
     * @param options 导出选项
     * @return 是否成功
     */
    bool addAEPulseSpectrumData(QtCSV::StringData& data, DataSpecificationGW::Spectrum* spectrum, const ExportOptions& options = ExportOptions());
    
    /**
     * @brief 添加AE波形图谱数据到CSV数据对象
     * @param data CSV数据对象
     * @param spectrum 图谱对象
     * @param options 导出选项
     * @return 是否成功
     */
    bool addAEWaveSpectrumData(QtCSV::StringData& data, DataSpecificationGW::Spectrum* spectrum, const ExportOptions& options = ExportOptions());
    
    /**
     * @brief 添加TEV幅值图谱数据到CSV数据对象
     * @param data CSV数据对象
     * @param spectrum 图谱对象
     * @param options 导出选项
     * @return 是否成功
     */
    bool addTEVAmpSpectrumData(QtCSV::StringData& data, DataSpecificationGW::Spectrum* spectrum, const ExportOptions& options = ExportOptions());
    
    /**
     * @brief 添加PRPD图谱数据到CSV数据对象
     * @param data CSV数据对象
     * @param spectrum 图谱对象
     * @param options 导出选项
     * @return 是否成功
     */
    bool addPRPDSpectrumData(QtCSV::StringData& data, DataSpecificationGW::Spectrum* spectrum, const ExportOptions& options = ExportOptions());
    
    /**
     * @brief 添加PRPS图谱数据到CSV数据对象
     * @param data CSV数据对象
     * @param spectrum 图谱对象
     * @param options 导出选项
     * @return 是否成功
     */
    bool addPRPSSpectrumData(QtCSV::StringData& data, DataSpecificationGW::Spectrum* spectrum, const ExportOptions& options = ExportOptions());
    
    /**
     * @brief 添加红外图谱数据到CSV数据对象
     * @param data CSV数据对象
     * @param spectrum 图谱对象
     * @param options 导出选项
     * @return 是否成功
     */
    bool addInfraredSpectrumData(QtCSV::StringData& data, DataSpecificationGW::Spectrum* spectrum, const ExportOptions& options = ExportOptions());
    
    /**
     * @brief 导出为JSON文件
     * @param filePath 目标文件路径
     * @param specification 数据规范对象
     * @return 是否成功
     */
    bool exportToJSONFile(const QString& filePath, DataSpecificationGW::DataSpecification* specification);
    
    /**
     * @brief 导出为XML文件
     * @param filePath 目标文件路径
     * @param specification 数据规范对象
     * @return 是否成功
     */
    bool exportToXMLFile(const QString& filePath, DataSpecificationGW::DataSpecification* specification);

    bool exportToCSV(QTextStream& out, DataSpecificationGW::DataSpecification* specification);
    /**
     * @brief 导出为CSV格式
     * @param out 输出流
     * @param specification 数据规范对象
     * @param options 导出选项
     * @return 是否成功
     */
    bool exportToCSV(QTextStream& out, DataSpecificationGW::DataSpecification* specification, const ExportOptions& options);
    // 添加exportToCSVFile方法实现
    bool exportToCSVFile(const QString& filePath,
                                         DataSpecificationGW::DataSpecification* specification,
                                         const ExportOptions& options);
    /**
     * @brief 导出为JSON格式
     * @param out 输出流
     * @param specification 数据规范对象
     * @return 是否成功
     */
    bool exportToJSON(QTextStream& out, DataSpecificationGW::DataSpecification* specification);
    
    /**
     * @brief 导出为XML格式
     * @param out 输出流
     * @param specification 数据规范对象
     * @return 是否成功
     */
    bool exportToXML(QTextStream& out, DataSpecificationGW::DataSpecification* specification);
    
    /**
     * @brief 导出文件头信息
     * @param out 输出流
     * @param specification 数据规范对象
     * @return 是否成功
     */
    bool exportFileHeader(QTextStream& out, DataSpecificationGW::DataSpecification* specification);
    
    /**
     * @brief 导出图谱头信息
     * @param out 输出流
     * @param spectrum 图谱对象
     * @return 是否成功
     */
    bool exportSpectrumHeader(QTextStream& out, DataSpecificationGW::Spectrum* spectrum);
    
    /**
     * @brief 将日期时间格式化为标准格式
     * @param dateTimeStr 原始日期时间字符串
     * @return 格式化后的日期时间
     */
    QString formatDateTime(const QString& dateTimeStr);
    
    // 导出AE幅值图谱
    bool exportAEAmpSpectrum(QTextStream& out, DataSpecificationGW::Spectrum* spectrum);
    
    // 导出AE相位图谱
    bool exportAEPhaseSpectrum(QTextStream& out, DataSpecificationGW::Spectrum* spectrum);
    
    // 导出AE脉冲图谱
    bool exportAEPulseSpectrum(QTextStream& out, DataSpecificationGW::Spectrum* spectrum);
    
    // 导出AE波形图谱
    bool exportAEWaveSpectrum(QTextStream& out, DataSpecificationGW::Spectrum* spectrum);
    
    // 导出TEV幅值图谱
    bool exportTEVAmpSpectrum(QTextStream& out, DataSpecificationGW::Spectrum* spectrum);
    
    // 导出PRPD图谱
    bool exportPRPDSpectrum(QTextStream& out, DataSpecificationGW::Spectrum* spectrum);
    
    // 导出PRPS图谱
    bool exportPRPSSpectrum(QTextStream& out, DataSpecificationGW::Spectrum* spectrum);
    
    // 导出红外图谱
    bool exportInfraredSpectrum(QTextStream& out, DataSpecificationGW::Spectrum* spectrum);
    
    // 导出未知类型图谱(通用方法)
    bool exportUnknownSpectrum(QTextStream& out, DataSpecificationGW::Spectrum* spectrum);
    
    /**
     * @brief 处理CSV字段中的特殊字符
     * @param field 原始字段内容
     * @return 处理后的字段内容
     */
    QString escapeCSVField(const QString& field);

    /**
     * @brief 将二进制数据转换为十六进制字符串
     * @param data 二进制数据
     * @param maxLength 最大长度，-1表示全部
     * @return 十六进制字符串
     */
    QString binaryToHexString(const QByteArray& data, int maxLength = 50);

    /**
     * @brief 将二进制数据转换为Base64编码
     * @param data 二进制数据
     * @return Base64编码字符串
     */
    QString binaryToBase64(const QByteArray& data);

private:
    static SpectrumExporter* s_instance;
    
    // 图谱类型到处理函数的映射
    QMap<int, std::function<bool(QTextStream&, DataSpecificationGW::Spectrum*)>> m_exportHandlers;
    
    // 当前处理的图谱索引
    int m_currentSpectrumIndex;
    
    // 总图谱数量
    int m_totalSpectrumCount;
};

#endif // SPECTRUMEXPORTER_H 
